#pragma once
#include "Comm.h"
#include "Buffer.h"
#ifdef COMM_MSVC
#define	R_OK	4		/* Test for read permission.  */
#define	W_OK	2		/* Test for write permission.  */
#define	X_OK	1		/* Test for execute permission.  */
#define	F_OK	0		/* Test for existence.  */
#endif

namespace COMM
{
	class COMM_API File
	{
		MYLIB_NONCOPIED_CLASS(File);
	public:
#ifndef COMM_MSVC
		class WriteUnMasker
		{
		public:
			WriteUnMasker();
			~WriteUnMasker();
		private:
			mode_t m_mask;
		};
#endif
		static bool Enum(const char* dir, const char* prefix, StringList& names, int postfix = 0);
		static bool MakeDir(const char* dir, int mode=0666); // mode must be 8 decimal.
		static bool ChangeMode(const char* src, int mode=0666);// mode must be 8 decimal.
		static bool Access(const char* src, int mode=F_OK);
		static bool Copy(const char* src, const char* dest, size_t block_size=4096);
		static bool Move(const char* src, const char* dest);
		static bool Remove(const char* src);
		static Buffer LoadContent(const char* filename);
		static String LoadContentText(const char* filename);
		static bool SaveContent(const char* filename, const void* buffer, size_t size);
		

		File();
		File(const char* filename, const char* mode);
		~File();
		bool Open(const char* filename, const char* mode);
		bool Close();

		FILE* Stream();
		const char* Name();
		bool IsOpened();
		long long Size();
		long long Position();
		bool MoveTo(long long position);
		bool MoveToBegin();
		bool MoveToEnd();
		// return 0 if feof or ferror. must flush after writing.
		size_t Read(void* buffer, size_t size);
		size_t Read(Buffer& buffer);
		File& operator >>(Buffer& buffer);
		bool Write(const void* buffer, size_t size);
		bool Write(const Buffer& buffer);
		bool WriteText(const char* format, ...);
		File& operator <<(const Buffer& buffer);
		bool Flush();

		bool Load(Buffer& content);
		// add ended '\0'. 
		bool LoadText(Buffer& content);
		
	private:
		bool LoadToMemory(Buffer& content, bool asText);
	private:
		ThreadLock m_lock;
		FILE* m_stream;
		String m_filename;
	};
}


